#pragma once
#include <map>
#include <memory>
#include <string>

namespace TrieTreeSpace
{
    class Node
    {
    public:
        int Pass = 0;
        int End = 0;
        bool IsCharExist(char Ch)
        {
            if(Nexts.count(Ch))
            {
                return true;
            }
            return false;
        }
        std::shared_ptr<Node> operator[](char Ch)
        {
            if(IsCharExist(Ch))
            {
                return Nexts[Ch];
            }
            return std::shared_ptr<Node>();
        }
        std::map<char,std::shared_ptr<Node>>Nexts;
    };
    using NodePtr = std::shared_ptr<Node>;

    class TrieTree
    {
    public:

        static void TrieTreeDemo()
        {
            TrieTree TT;
            TT.AddWord("happy");
            TT.AddWord("love");
            TT.AddWord("gorgeous");
            TT.AddWord("baby");
            TT.AddWord("beautiful");
            TT.AddWord("cute");
            TT.AddWord("humble");
            TT.AddWord("lucky");
            TT.AddWord("China");
            TT.AddWord("love");
            TT.AddWord("baber"); 
        }
        void AddWord(std::string Str)
        {
            NodePtr TempNode = BaseNode;
            for(auto& Ch:Str)
            {
                if(TempNode->IsCharExist(Ch))
                {
                    TempNode=TempNode[Ch];
                    TempNode->Pass++;
                }
                else
                {
                    TempNode->Nexts.insert(std::make_pair(Ch,NodePtr(new Node)));
                    TempNode=TempNode[Ch];
                    ++TempNode->Pass;
                }
            }
            TempNode->End++;
        }
        int IsWordExist(std::string Str)
        {
            NodePtr TempNode = BaseNode;
            for(auto& Ch:Str)
            {
                if(TempNode->IsCharExist(Ch))
                {
                    TempNode=TempNode[Ch];
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
        bool DeleteWord(std::string Str)
        {
            NodePtr TempNode = BaseNode;
            for(auto& Ch:Str)
            {
                if(TempNode->IsCharExist(Ch))
                {
                    TempNode=TempNode[Ch];
                }
                else
                {
                    return false;
                }
            }
        }
        int PrefixWordNum(std::string Str)
        {
            
        }
    private:
        NodePtr BaseNode;
    };
}
